package com.aura.lyngen.core.saver;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.aura.lyngen.constant.AppConstant;
import com.aura.lyngen.exception.BusinessException;
import com.aura.lyngen.exception.ErrorCode;
import com.aura.lyngen.model.enums.CodeGenTypeEnum;

import java.io.File;
import java.nio.charset.StandardCharsets;

/**
 * @ClassName CodeFileSaverTemplate
 * @Description 代码文件保存模板类
 * @Author ZJX
 * @Date 2025/9/1 16:12
 * @Version 1.0
 **/
public abstract class CodeFileSaverTemplate<T> {


    /**
     * 文件保存根目录
     */
    // todo: nginx 配置conf文件未成功
    protected static final String WEB_DIR = AppConstant.CODE_OUTPUT_ROOT_DIR;


    /**
     * 模板方法：保存代码的标准流程
     *
     * @param result 代码结果对象
     * @param appId  应用 ID
     * @return 保存的目录
     */
    public final File saveCode(T result, Long appId) {
        // 1. 验证输入
        validateInput(result);
        // 2. 构建唯一目录
        String baseDirPath = buildUniqueDir(appId);
        // 3. 保存文件（具体实现交给子类）
        saveFiles(result, baseDirPath);
        // 4. 返回文件目录对象
        return new File(baseDirPath);
    }

    /**
     * 构建文件的路径
     * 例如：HTML: web/code_output/html_当日时间_雪花 ID   时间精确到分钟
     * 例如：多文件: web/code_output/multi_file_当日时间_雪花 ID  时间精确到分钟
     * 雪花 ID 则使用其尾部几位进行区分。
     *
     * @param appId 应用 ID
     * @return 目录路径
     */
    protected String buildUniqueDir(Long appId) {
        if (appId == null) {
            throw new BusinessException(ErrorCode.PARAMS_INVALID_FORMAT, "应用 ID 不能为空");
        }
        String codeType = getCodeType().getValue();
        String uniqueDirName = StrUtil.format("{}_{}", codeType, appId);
        String dirPath = WEB_DIR + File.separator + uniqueDirName;  // 拼接目录路径
        FileUtil.mkdir(dirPath);  // 创建目录
        return dirPath;
    }

    /**
     * 验证输入参数（可由子类覆盖）
     *
     * @param result 代码结果对象
     */
    protected void validateInput(T result) {
        if (result == null) {
            throw new BusinessException(ErrorCode.PARAMS_NULL, "代码结果对象不能为空");
        }
    }

    /**
     * 获取代码生成类型
     *
     * @return 代码生成类型枚举
     */
    protected abstract CodeGenTypeEnum getCodeType();


    /**
     * 保存文件（具体实现交给子类）
     *
     * @param result      代码结果对象
     * @param baseDirPath 基础目录路径
     */
    protected abstract void saveFiles(T result, String baseDirPath);


    /**
     * 将内容写入指定文件（若文件不存在则创建，若存在则覆盖）
     * 注意：此方法会自动创建目录
     *
     * @param dirPath  目录路径（文件将被创建在此目录下）
     * @param filename 文件名（包含扩展名）
     * @param content  要写入的文件内容
     */
    public final void writeContentToFile(String dirPath, String filename, String content) {
        if (StrUtil.isBlank(dirPath) || StrUtil.isBlank(filename) || StrUtil.isBlank(content)) {
            throw new BusinessException(ErrorCode.PARAMS_NULL, "目录路径、文件名或内容不能为空");
        }
        String filePath = dirPath + File.separator + filename;
        FileUtil.writeString(content, filePath, StandardCharsets.UTF_8);
    }


}
